
package net.thelostlands.thelostmod;

import java.util.logging.Logger;

import net.thelostlands.thelostmod.Permissions.Perms;

import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;

/**
 * @author sleaker, faaabio
 *
 */
public class CmdHandler implements CommandExecutor {
	protected static final Logger log = Logger.getLogger("Minecraft");

	private static LostMod plugin;
	private PermHandler admins;

	CmdHandler(LostMod plugin) {
		CmdHandler.plugin = plugin;
		admins = plugin.getAdminHandler();
	}


	public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
		//Ignore the console and spit out the not implemented message
		if (sender instanceof ConsoleCommandSender) {
			sender.sendMessage("Console non implementata");
		} else if (sender instanceof Player) {
			//Otherwise lets try and do some stuff!
			Player player = (Player) sender;
            final String commandName = command.getName();
			if (commandName.equals("stealth")) {
				stealth(player);
				return true;
			} else if (commandName.equals("god")) {
				godMode(player);
				return true;
			} else if (commandName.equals("vanish")) {
				vanish(player);
				return true;
			} else if (commandName.equals("admin")) {
				adminMode(player);
				return true;
			} else if (commandName.equals("saveloc")) {
				saveLoc(player);
				return true;
			} else if (commandName.equals("return")) {
				returnLoc(player);
				return true;
			} else if (commandName.equals("adminstatus")) {
				adminStatus(player, args);
				return true;
			} else if (commandName.equals("fakeout")) {
				fakeLogout(player);
				return true;
			} else if (commandName.equals("fakein")) {
				fakeLogin(player);
				return true;
			} else if (commandName.equals("admin_bring")) {
				bring(player, args);
				return true;
			} else if (commandName.equals("admin_put")) {
				put(player, args);
				return true;
			} else if (commandName.equals("admin_tp")) {
				tp(player, args);
				return true;
			} else if (commandName.equals("admin_heal")) {
				heal(player, args);
				return true;
			} else if (commandName.equals("setmessage")) {
                            setMessage(player, args);
                        } else if (commandName.equals("getmessage")) {
                            getMessage(player, args);
                        }
		}
		return false;
	}

	private void heal(Player player, String[] args) {
		if ( !(Permissions.has(player, Perms.ADMINHEAL) || Permissions.has(player, Perms.ANYHEAL)) ) {
			player.sendMessage(Stringhe.NOPERMESSI);
			return;
		}
		if (! (PermHandler.isAdminMode(player.getName()) || Permissions.has(player, Perms.ANYHEAL)) ) {
			player.sendMessage(Stringhe.NOPERMESSIADMIN);
			return;
		} 
		if (args.length == 0) {
			player.setHealth(20);
			return;
		}
		if (args[0].equalsIgnoreCase("tutti") || args[0].equalsIgnoreCase("all")) {
			for ( Player target : plugin.getServer().getOnlinePlayers() ){
				target.setHealth(20);
				target.sendMessage("Una persona molto importante ha voluto prendersi cura di te..");
			}
			return;
		}
		int counter =0;
		for (Player target : plugin.getServer().getOnlinePlayers()) {
			for(String arg : args){
				if(target.getName().equals(arg)){
					target.setHealth(20);
					counter++;					
					player.sendMessage("Hai gentilmente curato "+target.getName()+", te ne sar� grato per sempre.");
					target.sendMessage("Una persona molto importante ha voluto prendersi cura di te..");
					if (counter>=args.length) return;
				}
			}			
		}
		if(counter==0){
			player.sendMessage("Non � stato possibile rintracciare nessun con tal soprannome!");
		}
	}

	private void bring(Player player, String[] args) {
		if (!Permissions.has(player, Perms.ADMINTP) && !Permissions.has(player, Perms.ANYTP)) {
			player.sendMessage(Stringhe.NOPERMESSI);
			return;
		} else if (!PermHandler.isAdminMode(player.getName()) && !Permissions.has(player, Perms.ANYTP)) {
			player.sendMessage(Stringhe.NOPERMESSIADMIN);
			return;
		} else if (args.length < 1) {
			player.sendMessage("Dovete specificare chi portare al vostro cospetto");
			return;
		} else {
			if (args[0].equalsIgnoreCase("all") || args[0].equalsIgnoreCase("tutti")) {
				for (Player p : plugin.getServer().getOnlinePlayers()) {
					if(p!=player) {
						p.teleport(player.getLocation());						
					}					
				}
				plugin.getServer().broadcastMessage(player.getName()+ " ha portato tutti dinnanzi al suo cospetto.");
				return;
			} else {
				boolean match = false;
				for (Player p : plugin.getServer().getOnlinePlayers()) {
					for(String arg : args){
						if (p.getName().equals(arg)) {
							match=true;
							p.teleport(player.getLocation());
							p.sendMessage(player.getName()+" ha richiesto la tua presenza.");
						}
					}
				}
				if (!match)
					player.sendMessage(Stringhe.NESSUNO);

				return;
			}
		}
	}

	private void put(Player player, String[] args) {
		Block block = player.getTargetBlock(null, 100).getRelative(BlockFace.UP);
		if (!Permissions.has(player, Perms.ADMINTP) && !Permissions.has(player, Perms.ANYTP)) {
			player.sendMessage(Stringhe.NOPERMESSI);
			return;
		} else if (!PermHandler.isAdminMode(player.getName()) && !Permissions.has(player, Perms.ANYTP)) {
			player.sendMessage(Stringhe.NOPERMESSIADMIN);
			return;
		} else if (args.length < 1) {
			player.sendMessage("Dovete specificare almeno un giocatore da fiondare sul vostro sguardo.");
			return;
		} else if (block == null){
			player.sendMessage("I vostri occhi guardano troppo lontano.. siete tanto avanti che se vi voltate indietro vedete il futuro.");
		} else if (args[0].equalsIgnoreCase("all") || args[0].equalsIgnoreCase("tutti")) {
			for(Player target : plugin.getServer().getOnlinePlayers()){
				if(!target.equals(player)) target.teleport(block.getLocation());
			}
			plugin.getServer().broadcastMessage(player.getName()+" ha lanciato tutti verso il suo sguardo");
		} else {
			int counter =0;
			for (Player target : plugin.getServer().getOnlinePlayers()) {
				for(String arg : args){
					if (arg.equals(target.getName())){
						counter++;
						target.teleport(block.getLocation());
						target.sendMessage(player.getName()+ " ha preteso che tu fossi l�.");
					}
				}
			}
			if (counter==0)
				player.sendMessage(Stringhe.NESSUNO);
			return;
		}
	}

	private void tp(Player player, String[] args) {
		if (!Permissions.has(player, Perms.ADMINTP) && !Permissions.has(player, Perms.ANYTP)) {
			player.sendMessage(Stringhe.NOPERMESSI);
			return;
		} else if (!PermHandler.isAdminMode(player.getName()) && !Permissions.has(player, Perms.ANYTP)) {
			player.sendMessage(Stringhe.NOPERMESSIADMIN);
			return;
		} else if (args.length < 1) {
			player.sendMessage("Devi almeno specificare un argomento (un giocatore, coordinate..)");
			return;
		}
		if (args.length == 1) {
			Player target = null;
			target = plugin.getServer().getPlayer(args[0]);
			if (target == null) {
				player.sendMessage(Stringhe.NESSUNO);
			} else {
				player.teleport(target.getLocation());
			}
		} 
		//Assume teleporting one player to another if 2 args
		else if (args.length == 2) {
			Player target = null;
			Player sent = null;
			target = plugin.getServer().getPlayer(args[0]);
			sent = plugin.getServer().getPlayer(args[1]);
			if (sent == null) {
				player.sendMessage(Stringhe.NESSUNO+ " ("+args[0]+").");
			} else if (target == null) {
				player.sendMessage(Stringhe.NESSUNO+" ("+args[1]+").");
			} else if (target == sent) {
				player.sendMessage("Non giocate con i vostri poteri, potrebbero voltarsi contro di voi.");
			} else {
				sent.teleport(target.getLocation());
				player.sendMessage("Ai suoi ordini.");
			}
		}
		//Assume coordinate if 3 args
		else if (args.length == 3) {
			try {
				int x = Integer.parseInt(args[0]);
				int y = Integer.parseInt(args[1]);
				int z = Integer.parseInt(args[2]);
				player.teleport(new Location(player.getWorld(), x, y, z));
			} catch (Exception e) {
				player.sendMessage("Non riesco a capire il vostro sistema di coordiante. Che servo stupido, vado a fustigarmi");
			}
			return;
		}
	}



	/**
	 * Sends a fake logout message to all players connected that do not have all-messages permission
	 * 
	 */
	public void fakeLogout(Player player) {
		if (Permissions.has(player, Perms.FAKELOG)) {
			PermHandler.fakeLog(player.getName(), false);
		} else {
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Sends a fake login message to all players connected that do not have all-messages permission
	 * 
	 */
	public void fakeLogin(Player player) {
		if (Permissions.has(player, Perms.FAKELOG)) {
			PermHandler.fakeLog(player.getName(), true);
		} else {
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Lists what admin modes a player currently has.
	 * 
	 * @param player
	 * @param args
	 */
	public void adminStatus (Player player, String[] args) {
		if (Permissions.hasAny(player)) {
			if (args.length < 1) {
				//send string of info for this player;
				player.sendMessage(PermHandler.infoString(player));
			} else if (Permissions.has(player, Perms.STATUS)) {
				Player target = plugin.getServer().getPlayer(args[0]);
				if(target!=null){
					player.sendMessage(PermHandler.infoString(target));
				}
				else {
						player.sendMessage(Stringhe.NESSUNO);
				}				
			}
		} else {
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Checks permissions for using /return
	 * then attempts to return the player to a saved location
	 */
	public void returnLoc (Player player) {
		if (Permissions.has(player, Perms.RETURN)) {
			if (!admins.returnPlayer(player)) 
				player.sendMessage("Non ricordo che mi abbia detto di salvare una posizione, ero distratto nell'ammirarla. Il suo perdono o la mia vita.");
		} else {
			//If they don't have permissions let them know
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Checks permissions then: 
	 * Saves a players current location to the admin map
	 * 
	 * @param player
	 */
	public void saveLoc (Player player) {
		String playerName = player.getName();
		if (Permissions.has(player, Perms.RETURN)) {
			if (!PermHandler.contains(playerName))
				PermHandler.add(playerName);

			PermHandler.setOrigin(playerName, player.getLocation());
			PermHandler.savePlayer(playerName);
			player.sendMessage("Non dimentichero' mai codesto luogo: " + ChatColor.DARK_AQUA + PermHandler.getLocationString(playerName));
		} else {
			//If they don't have permissions let them know
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Toggles admin-mode for a player
	 * God, NoPickup, Stealth, Invis + Saves Location or
	 * Disables them and returns to the saved location
	 * 
	 * @param player
	 */
	public void adminMode (Player player) {
		String playerName = player.getName();
		if (Permissions.has(player, Perms.ADMINMODE)) {
			//If this player is already in admin-mode - toggle it off.
			if(PermHandler.isAdminMode(playerName)) {
				PermHandler.setAdminMode(playerName, false);
				PermHandler.fakeLog(playerName, true);
				admins.goVisible(player);
				player.sendMessage(ChatColor.RED + "Modalita' amministratore " + ChatColor.RED + "DISABILITATA.");
				//Return the player a half-second later
				admins.returnPlayer(player);
			} else {
				//Check if this player is in the admin map - add if necessary
				if (!PermHandler.contains(playerName))
					PermHandler.add(playerName);
				//Enable adminmode and send the message
				PermHandler.setAdminMode(playerName, true);
				PermHandler.fakeLog(playerName, false);
				admins.goInvisibleInitial(player);
				player.sendMessage(ChatColor.GREEN + "Modalita' amministratore " +ChatColor.GREEN + "ABILITATA.");
				//Save the players current location as their origin.
				PermHandler.setOrigin(playerName, player.getLocation());
				player.sendMessage("Ora che sei un admin, mi ricordero' questo posto: " + ChatColor.BLUE + PermHandler.getLocationString(playerName)+". Usa /ritorna per tornarci.");
			}
			PermHandler.savePlayer(playerName);
		} else {
			//If they don't have permissions let them know
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Toggles god-mode for the player
	 * 
	 * @param player
	 */
	public void godMode (Player player) {
		String playerName = player.getName();
		if (Permissions.has(player, Perms.GOD)) {
			//If this player is already in god-mode - toggle it off.
			if(PermHandler.isGod(playerName)) {
				PermHandler.setGod(playerName, false);
				player.sendMessage(ChatColor.RED + "Modalita' dio " +ChatColor.RED + "DISATTIVATA");
			} else {
				//Check if this player is in the admin map - add if necessary
				if (!PermHandler.contains(playerName)) {
					PermHandler.add(playerName);
				}

				//Now enable it and send the message
				PermHandler.setGod(playerName, true);
				player.sendMessage(ChatColor.GREEN + "Modalita' dio "  + ChatColor.GREEN + "ATTIVATA.");
			}
			PermHandler.savePlayer(playerName);
		} else {
			//If they don't have permissions let them know
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Toggles stealth login/logoff mode
	 * 
	 * 
	 * @param player
	 */
	public void stealth (Player player) {
		String playerName = player.getName();
		//Check permissions to use the command
		if (Permissions.has(player, Perms.STEALTH)) {
			//If the player is already stealthed, disable and send them a message
			if (PermHandler.isStealthed(playerName)) {
				PermHandler.setStealthed(playerName, false);
				PermHandler.fakeLog(playerName, true);
				player.sendMessage(ChatColor.RED + "Modalita' furtiva " +  ChatColor.RED + " DISATTIVATA.");
			} else {
				//Check if this player is in the admin map - add if necessary
				if (!PermHandler.contains(playerName))
					PermHandler.add(playerName);
				//Now enable stealth mode and send the messages
				PermHandler.setStealthed(playerName, true);
				PermHandler.fakeLog(playerName, false);
				player.sendMessage(ChatColor.GREEN + "Modalita' furtiva " +  ChatColor.GREEN + "ATTIVATA.");
			}
			PermHandler.savePlayer(playerName);
		} else {
			//If they don't have permissions let them know
			Permissions.noPermsMessage(player);
		}
	}

	/**
	 * Toggles the player being invisible/visible to players
	 * Also toggles off Picking up of items while invisibility is on.
	 * 
	 * @param player
	 */
	public void vanish (Player player) {
		String playerName = player.getName();
		//Check permissions to use the command
		if (Permissions.has(player, Perms.VANISH)) {
			//If the player is already vanished - unvanish them.
			if (PermHandler.isInvisible(playerName)) {
				PermHandler.setInvis(playerName, false);
				PermHandler.setNoPickup(playerName, false);
				admins.goVisible(player);
				player.sendMessage(ChatColor.RED + " Invisibile e no-pickup: " + ChatColor.RED + "DISATTIVATO.");
			} else {
				//Check if the player is in the admin map - add if not
				if (!PermHandler.contains(playerName))
					PermHandler.add(playerName);
				//Now enable invis, no pickup and send the message
				PermHandler.setInvis(playerName, true);
				PermHandler.setNoPickup(playerName, true);
				admins.goInvisibleInitial(player);
				player.sendMessage(ChatColor.GREEN + " Invisibile e no-pickup: " + ChatColor.GREEN + "ATTIVATO.");
			}
			PermHandler.savePlayer(playerName);
		} else {
			//Let the player know they don't have permission
			Permissions.noPermsMessage(player);
		}
	}

    public void setMessage(Player player, String[] args) {
        if(Permissions.has(player,Perms.ALL_MESSAGES)){//ha i permessi
           if(args.length<1){
               player.sendMessage("Non hai impostato il nuovo messaggio");
               
           }
           
           else{
               String message =args[0];
               int counter = 1;
               while(counter<args.length-1){
                   message+=" "+args[counter++];
               }
               
               try {
                   plugin.mercury.setSeconds(Integer.parseInt(args[counter]));
               } catch (Exception e) {
                   message+=" "+args[counter];
               } finally {
                   plugin.mercury.setRawMessage(message);
                   plugin.changeConfigFile();
                   if(plugin.mercury.getSeconds()>0){
                       plugin.mercury.restart();
                   }else {
                       plugin.mercury.stop();
                   }
               }

           }
        }
    }

    private void getMessage(Player player, String[] args) {
        player.sendMessage(plugin.mercury.getRawMessage()+" viene stampato ogni "+plugin.mercury.getSeconds()+ " secondi");
    }
}
